package com.qgzj.config;

import com.alibaba.fastjson.JSONException;
import com.google.common.collect.Iterators;
import com.qgzj.exception.QgzjException;
import com.qgzj.exception.QgzjStudyExceptionEnum;
import com.qgzj.response.CommonRes;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.stream.Collectors;

/**
 * @Description: exception全局控制器
 * @Author: huixiangyin
 * @CreateTime: 2018/2/9 15:39
 */
@ResponseBody
@ControllerAdvice
public class ExceptionsHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${sso.url}")
    private String ssoUrl;

    @Value("${domain}")
    private String domain;

    @Value("${union.no}")
    private String unionNo;

    @ExceptionHandler({QgzjException.class})
    public CommonRes<?> handleQgzjException(QgzjException ee) {

        logger.error("请求失败QgzjException：{}",  ExceptionUtils.getStackTrace(ee));

//        // 未登录异常 返回增加登录地址
//        Integer systemCode = getLoginSystemCode(ee);
//        if (null != systemCode) {
//            StringBuffer redirectSb = new StringBuffer(ssoUrl);
//            redirectSb.append("user/login.htm?unionNo=");
//            redirectSb.append(unionNo);
//            redirectSb.append("&systemCode=");
//            redirectSb.append(systemCode);
//            redirectSb.append("&redirectUrl=");
//            redirectSb.append(getRedirectUrl(systemCode));
//            return CommonRes.fail(ee, redirectSb.toString());
//        }

        return CommonRes.fail(ee);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public CommonRes exceptionHandler(ConstraintViolationException exception) {
        logger.error("请求失败ConstraintViolationException exception: {}", ExceptionUtils.getStackTrace(exception));
        CommonRes<Object> result = new CommonRes<>();
        result.setStatus(QgzjStudyExceptionEnum.FAIL.getStatus());
        result.setMsg(exception.getConstraintViolations().stream().map(this::mapToFieldError).collect(
                Collectors.toList()).toString());

        return result;
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonRes exceptionHandler(MethodArgumentNotValidException exception) {
        logger.error("请求失败MethodArgumentNotValidException exception: {}", ExceptionUtils.getStackTrace(exception));
        CommonRes<Object> result = new CommonRes<>();
        result.setStatus(QgzjStudyExceptionEnum.FAIL.getStatus());
        result.setMsg(exception.getBindingResult().getAllErrors().stream().map(this::mapToFieldError).collect(
                Collectors.toList()).toString());

        return result;
    }

    @ExceptionHandler(JSONException.class)
    public CommonRes exceptionHandler(JSONException exception) {
        logger.error("请求失败JSONException exception: {}", ExceptionUtils.getStackTrace(exception));
        CommonRes<Object> result = new CommonRes<>();
        result.setStatus(QgzjStudyExceptionEnum.FAIL.getStatus());
        result.setMsg("json 解析异常 ：" + exception.getMessage());

        return result;
    }

    @ExceptionHandler(Exception.class)
    public CommonRes exceptionHandler(Exception exception) {
        logger.error("请求失败Exception: {}", ExceptionUtils.getStackTrace(exception));
        CommonRes<Object> result = new CommonRes<>();
        result.setStatus(QgzjStudyExceptionEnum.FAIL.getStatus());
        result.setMsg(QgzjStudyExceptionEnum.FAIL.getMessage());
        return result;
    }

    private String mapToFieldError(ObjectError error) {
        MessageSourceResolvable messageSourceResolvable = (MessageSourceResolvable) error.getArguments()[0];

        return String.format("%s : %s", messageSourceResolvable.getDefaultMessage(), error.getDefaultMessage());
    }

    private String mapToFieldError(ConstraintViolation<?> violation) {
        return String.format("%s : %s", getFieldName(violation), violation.getMessage());
    }

    private String getFieldName(ConstraintViolation<?> violation) {
        Path path = violation.getPropertyPath();
        return Iterators.getLast(path.iterator()).getName();
    }


//    /**
//     * 登陆code
//     * @param ee
//     * @return
//     */
//    private Integer getLoginSystemCode(QgzjException ee){
//        if (ee.getCode().equals(QgzjMedicalExceptionEnum.NOT_LOGIN.getStatus())) {
//            return SystemCodeEnum.MEDICAL.getCode();
//        }else if(ee.getCode().equals(QgzjMedicalExceptionEnum.PC_NOT_LOGIN.getStatus())){
//            return SystemCodeEnum.PC.getCode();
//        }else if(ee.getCode().equals(QgzjMedicalExceptionEnum.WECHAT_NOT_LOGIN.getStatus())){
//            return SystemCodeEnum.H5.getCode();
//        }else{
//            return null;
//        }
//    }
//
//    /**
//     * 根据选择获取跳转url
//     * @param systemCode
//     * @return
//     */
//    private String getRedirectUrl(Integer systemCode){
//        if (systemCode.equals(SystemCodeEnum.MEDICAL.getCode())){
//        	return new StringBuilder(domain).append("admin/").toString();
//        }else if(systemCode.equals(SystemCodeEnum.PC.getCode())){
//            return new StringBuilder(domain).append("pc/index.htm").toString();
//        }else{
//            return new StringBuilder(domain).append("wechat/index.htm").toString();
//        }
//    }

}